package pe.edu.upla.lamerced.DAO.impl;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import pe.edu.upla.lamerced.DAO.HospedajeDAO;
import pe.edu.upla.lamerced.bean.Detallefactura;
import pe.edu.upla.lamerced.bean.Factura;
import pe.edu.upla.lamerced.bean.Habitacion;
import pe.edu.upla.lamerced.bean.Hospedaje;

/**
 * estado 0 = reserva finalizada<br/>
 * estado 1 = reservado <br/>
 * estado 2 = hospedaje<br/>
 * estado 3 = hospedaje finalizado<br/>
 * 
 * @author elvis
 *
 */
@Repository
public class HospedajeDAOImpl extends HibernateDaoSupport implements HospedajeDAO {

	public HospedajeDAOImpl(){}
	
	@Autowired
	public HospedajeDAOImpl(SessionFactory sessionFactory){
		setHibernateTemplate( new HibernateTemplate(sessionFactory));
	}
	
	@Override
	@Transactional(propagation=Propagation.REQUIRES_NEW)
	public void registrarHospedaje(Hospedaje hospedaje) {
		this.getHibernateTemplate().merge(hospedaje);
		this.getHibernateTemplate().merge(hospedaje.getHabitacion());
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRES_NEW)
	public void registrarHospedajeReserva(Hospedaje hospedaje) {
		this.getHibernateTemplate().persist(hospedaje);
	}


	@Override
	@Transactional(propagation=Propagation.MANDATORY)
	public void registrarReserva(Hospedaje hospedaje) {
		this.getHibernateTemplate().persist(hospedaje);
	}

	@Override
	public Hospedaje obtenerReserva(Integer idhospedaje) {
		Query query = getSession().createQuery("select h from Hospedaje h inner join h.habitacion ha where h.estado = 1 and ha.estado=1 and idhospedaje = :id  ")
        .setInteger("id", idhospedaje);
        Hospedaje h = (Hospedaje)query.uniqueResult();        
		System.out.println(h.toString());
		return h;
	}

	@Override
	public Hospedaje obtenerHospedaje(Integer idhospedaje) {
		Query query = getSession().createQuery(" from Hospedaje h where idhospedaje = :id  ")
        .setInteger("id", idhospedaje);
        Hospedaje h = (Hospedaje)query.uniqueResult();        
		System.out.println(h.toString());
		return h;
	}

	
	@SuppressWarnings("unchecked")
	@Override
	public List<Hospedaje> listarRserva(Hospedaje hospedaje) {	
		Criteria crit = getSession().createCriteria(Hospedaje.class);
		if(hospedaje.getEstado()==null){
			crit.add(Restrictions.eq("estado",1));
		}else{
			crit.add(Restrictions.eq("estado",hospedaje.getEstado()));
		}  
		
		  if(hospedaje.getUsersByIdUsuarioCli()!=null){
			  Criteria crit2 = crit.createCriteria("usersByIdUsuarioCli");
			  crit2.add(Restrictions.eq("username",hospedaje.getUsersByIdUsuarioCli().getUsername()));
		  }
		  if(hospedaje.getHabitacion()!=null){			  
			  if(hospedaje.getHabitacion().getEstado()!=null){
				  Criteria crit2 = crit.createCriteria("habitacion");
				  crit2.add(Restrictions.eq("estado",hospedaje.getHabitacion().getEstado()));
			  }			  
		  }
		return crit.list();
	}

	@Override
	@Transactional(propagation=Propagation.MANDATORY)
	public void finalizarreserva(Hospedaje hospedaje) {		
		this.getHibernateTemplate().saveOrUpdate(hospedaje);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Hospedaje> listaHospedajes(String usuario) {
		if(!usuario.equals("")){
			Query query = getSession().createQuery(" from Hospedaje h where estado in ('2','3')  and usersByIdUsuarioCli.username = :usuario  ")
	        .setString("usuario", usuario);
			return query.list();
		}
		return this.getHibernateTemplate().find("from Hospedaje h where estado in ('2','3') ");
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Habitacion> buscarHabitacionesdisponibles(Hospedaje h) {
		//TODO: pendiente query que me diga las habitaciones que no tienen reserva
		//el dia que se indica
		return this.getHibernateTemplate()
		.find("select h from Habitacion h  ");
	}

	@Override
	public void anularReserva(int codigo) {
		Hospedaje h = obtenerReserva(codigo);
		h.setEstado(0);
		h.getHabitacion().setEstado(0);
		
		this.getHibernateTemplate().merge(h);
		this.getHibernateTemplate().merge(h.getHabitacion());
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Hospedaje> listaHospedajesActivos() {
		return this.getHibernateTemplate().find("select h from Hospedaje h where estado = 2");
	}

	@Override
	@Transactional(propagation=Propagation.MANDATORY)
	public void registrarFactura(Factura fac, List<Detallefactura> lisDet) {
		this.getHibernateTemplate().persist(fac);
		this.getHibernateTemplate().merge(fac.getHospedaje());
		this.getHibernateTemplate().merge(fac.getHospedaje().getHabitacion());
		for(Detallefactura det : lisDet){
			this.getHibernateTemplate().persist(det);	
		}
	}
	
}
